Imports System.Drawing

Public Class FloodFillBitmap

    Dim newValue, oldValue As Double 'values to replace if necessary
    Dim boxX, boxY As Integer 'value of BOX[x=width,y=height] within which values should be replaced

    Public Enum FloodFillType
        WhereValueMatches = 1
        InsideABox = 2
    End Enum

    Dim CurrentFloodFillingType As New FloodFillType

    Sub New(ByVal newValueToBePutIn As Double, ByVal oldValueToReplace As Double)
        Me.newValue = newValueToBePutIn
        Me.oldValue = oldValueToReplace
        Me.boxX = 0
        Me.boxY = 0
        Me.CurrentFloodFillingType = FloodFillType.WhereValueMatches
    End Sub
    Sub New(ByVal boxX As Integer, ByVal boxY As Integer, ByVal boxZ As Integer, ByVal valuetoDetect As Double, ByVal ValuetoPutIn As Double)
        Me.boxX = boxX
        Me.boxY = boxY
        Me.newValue = ValuetoPutIn
        Me.oldValue = valuetoDetect
        Me.CurrentFloodFillingType = FloodFillType.InsideABox
    End Sub

    Public Sub FloodFill4(ByRef Data As Bitmap, ByVal Seedx As Integer, ByVal Seedy As Integer)

        If Seedx > Data.Width - 1 Or Seedx < 0 Then Exit Sub
        If Seedy > Data.Height - 1 Or Seedy < 0 Then Exit Sub

        Select Case Me.CurrentFloodFillingType
            Case FloodFillType.InsideABox
                Dim Detected As Boolean = True
                'First detect that the new gap matches the size of Box
                For i As Integer = 0 To boxX - 1
                    For j As Integer = 0 To boxY - 1
                        If Data.GetPixel(Seedx + i, Seedy + j).R <> oldValue Then Detected = False
                    Next
                Next
                'If it is of the size of the box or bigger
                If Detected Then
                    Me.CurrentFloodFillingType = FloodFillType.WhereValueMatches
                    FloodFill4(Data, Seedx, Seedy)
                    Me.CurrentFloodFillingType = FloodFillType.InsideABox 'reset
                End If

            Case FloodFillType.WhereValueMatches
                If Data.GetPixel(Seedx, Seedy).R = Me.oldValue Then Data.SetPixel(Seedx, Seedy, Color.FromArgb(Me.newValue, Me.newValue, Me.newValue))
                Me.FloodFill4(Data, Seedx + 1, Seedy)
                Me.FloodFill4(Data, Seedx - 1, Seedy)
                Me.FloodFill4(Data, Seedx, Seedy + 1)
                Me.FloodFill4(Data, Seedx, Seedy - 1)
        End Select
    End Sub

    Public Sub FloodFill8(ByRef Data As Bitmap, ByVal Seedx As Integer, ByVal Seedy As Integer)

        If Seedx > Data.Width - 1 Or Seedx < 0 Then Exit Sub
        If Seedy > Data.Height - 1 Or Seedy < 0 Then Exit Sub

        Select Case Me.CurrentFloodFillingType
            Case FloodFillType.InsideABox
                Dim Detected As Boolean = True
                'First detect that the new gap matches the size of Box
                For i As Integer = 0 To boxX - 1
                    For j As Integer = 0 To boxY - 1
                        If Data.GetPixel(Seedx + i, Seedy + j).R <> oldValue Then Detected = False
                    Next
                Next
                'If it is of the size of the box or bigger
                If Detected Then
                    Me.CurrentFloodFillingType = FloodFillType.WhereValueMatches
                    FloodFill8(Data, Seedx, Seedy)
                    Me.CurrentFloodFillingType = FloodFillType.InsideABox 'reset
                End If

            Case FloodFillType.WhereValueMatches
                If Data.GetPixel(Seedx, Seedy).R = Me.oldValue Then Data.SetPixel(Seedx, Seedy, Color.FromArgb(Me.newValue, Me.newValue, Me.newValue))
                '6 from before
                Me.FloodFill8(Data, Seedx + 1, Seedy)
                Me.FloodFill8(Data, Seedx - 1, Seedy)
                Me.FloodFill8(Data, Seedx, Seedy + 1)
                Me.FloodFill8(Data, Seedx, Seedy - 1)
                'now all diagonals
                Me.FloodFill8(Data, Seedx - 1, Seedy + 1)
                Me.FloodFill8(Data, Seedx - 1, Seedy - 1)
                Me.FloodFill8(Data, Seedx + 1, Seedy + 1)
                Me.FloodFill8(Data, Seedx + 1, Seedy - 1)
        End Select

    End Sub
End Class


